package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.player.UserBeauty;
import com.yanqu.road.entity.player.UserColdRoomSite;
import com.yanqu.road.logic.bussiness.player.UserColdRoomBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.ColdRoomPb;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 冷宫模块
 */
public class ColdRoomModule extends GeneralModule {
    private Map<Integer, UserColdRoomSite> userColdRoomSiteMap;

    public ColdRoomModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        userColdRoomSiteMap = UserColdRoomBussiness.getUserColdRoomSiteMap(player.getUserId());

        try {
            for (UserColdRoomSite userColdRoomSite : userColdRoomSiteMap.values()) {
                UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(userColdRoomSite.getBeautyId());
                if (userBeauty == null) {
                    userColdRoomSite.setBeautyId(0);
                }
            }
        } catch (Exception e) {
            log.error(e);
        }

        return true;
    }

    @Override
    public boolean afterLoadData() {
        initColdRoomSystem(false);
        return true;
    }

    @Override
    public void afterLogin() {
        syncColdRoomSiteData(userColdRoomSiteMap);
    }

    @Override
    public void loginSendMsg() {

    }

    @Override
    public boolean saveData() {
        for (UserColdRoomSite coldRoomSite : userColdRoomSiteMap.values()) {
            if (coldRoomSite.isInsertOption()) {
                UserColdRoomBussiness.addUserColdRoomSite(coldRoomSite);
            } else if (coldRoomSite.isUpdateOption()) {
                UserColdRoomBussiness.updateUserColdRoomSite(coldRoomSite);
            }
        }
        return true;
    }

    /**
     * 一键领取
     */
    public long oneKeyHarvest(long timeMillis) {
        // 先计算收益
        long harvest = 0;
        for (UserColdRoomSite site : userColdRoomSiteMap.values()) {
            if (site.getBeautyId() == 0) {
                continue;
            }
            long add = calcSiteHarvest(site, timeMillis);
            if (add == 0) {
                continue;
            }
            harvest += add;
            site.setLastRestoreTime(timeMillis);

        }
        // 加道具
        addProperty(harvest);
        return harvest;
    }

    /**
     * 加道具
     * @param harvest
     */
    private void addProperty(long harvest) {
        if (harvest <= 0) {
            return;
        }
        Property property = new Property(GameConfig.COLDROOM_HARVEST_ID, BigInteger.valueOf(harvest));
        player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.ColdRoom, eLogMoneyType.ColdRoomOneKeyHarvest);
    }

    /**
     * 召回美女
     */
    public long callBackBeauty(UserColdRoomSite site, long timeMillis) {
        // 先计算收益
        long harvest = calcSiteHarvest(site, timeMillis);
        site.setLastRestoreTime(0);
        site.setBeautyId(0);
        // 加道具
        addProperty(harvest);
        return harvest;
    }

    /**
     * 派遣美女
     */
    public void dispatchBeauty(UserColdRoomSite site, int beautyId, long timeMillis) {
        site.setLastRestoreTime(timeMillis);
        site.setBeautyId(beautyId);
    }

    /**
     * 扩展坑位
     * @param siteIndex 下一个解锁的起始坑位
     */
    public int extendSite(int siteIndex) {

        //新逻辑
        //织布机临界判断数量|一组解锁的织布机数量(若当前为解锁的第N组织布机则解锁第N组织布机所需的满足条件——玩家当前美女数量>(临界数量+一组解锁数量*N）+最少在绣房外的美女数量
        // （玩家当前美女数量小于等于临界数量时，正常解锁，无条件限制）
        List<Integer> judgmentList = StringUtils.stringToIntegerList(GameConfig.COLDROOM_LOOMS_INCREASE_JUDGMENT, "\\|");
        if(judgmentList.size() != 2){
            return GameErrorCode.E_GAME_ERROR;
        }

        // 已经扩增的席位数量
        int increaseNum = userColdRoomSiteMap.size() - GameConfig.COLDROOM_INIT_SITE;
        // 单席位价格
        int price = increaseNum * GameConfig.COLDROOM_INCREASE_PRICE + GameConfig.COLDROOM_BASE_PRICE;
        price = price > GameConfig.COLDROOM_MAX_PRICE ? GameConfig.COLDROOM_MAX_PRICE : price;

        //临界数量
        int unLimitSiteNum = judgmentList.get(0);
        //每次解锁的数量
        int groupNum = judgmentList.get(1);

        //临界，需要判断美女數量
        if(userColdRoomSiteMap.size() >= unLimitSiteNum){
            //一组一组解锁
            int n = ((userColdRoomSiteMap.size() - unLimitSiteNum) / groupNum) + 1;
            //美女数量是否足够
            int needBeautyNum = unLimitSiteNum + groupNum * n + GameConfig.COLDROOM_FREE_BEAUTY_NUM;
            int beautyCount = player.getModule(BeautyModule.class).getBeautyCount();
            if(beautyCount < needBeautyNum){
                return GameErrorCode.E_BEAUTY_COUNT_NO_ENOUGH;
            }
        }

        //一个一个解锁
        //消耗
        if (!player.getModule(CurrencyModule.class).removeCurrency(new Property(GameConfig.GAME_MONEY_INGOTS, BigInteger.valueOf(price)),
                eLogMoneyType.ColdRoom, eLogMoneyType.ColdRoomExtendSite)) {
            return GameErrorCode.E_BAG_INGOTS_NO_ENOUGH;
        }
        UserColdRoomSite site = new UserColdRoomSite();
        site.setUserId(player.getUserId());
        site.setSiteIndex(siteIndex);
        site.setInsertOption();
        userColdRoomSiteMap.put(siteIndex, site);
        return 0;
    }


    public void initColdRoomSystem(boolean isSendMsg){
        //TODO 加系统解锁
//        if(SystemOpenMgr.systemOpen(player, eSystemId.ColdRoom.getValue())) {
            if(userColdRoomSiteMap == null || userColdRoomSiteMap.isEmpty()){
                initColdRoomSiteMap();
            }
            if(isSendMsg){
                syncColdRoomSiteData(userColdRoomSiteMap);
            }
//        }
    }

    private void initColdRoomSiteMap() {
        userColdRoomSiteMap = new ConcurrentHashMap<>();
        for (int i = 0; i < GameConfig.COLDROOM_INIT_SITE; i++) {
            UserColdRoomSite site = new UserColdRoomSite();
            site.setUserId(player.getUserId());
            site.setSiteIndex(i+1);
            site.setInsertOption();
            userColdRoomSiteMap.put(i+1, site);
        }
    }

    /**
     * 判断美女是否在织布中
     * @param beautyId
     * @return
     */
    public boolean isBeautyFree(int beautyId) {
        if (beautyId == 0) {
            return false;
        }
        boolean isFree = true;
        for (UserColdRoomSite site : userColdRoomSiteMap.values()) {
            if (site.getBeautyId() == beautyId) {
                isFree = false;
                break;
            }
        }
        return isFree;
    }

    /**
     * 冷宫美女数量
     */
    public int getColdRoomBeautyCount(){
        int count = 0;
        for (UserColdRoomSite site : userColdRoomSiteMap.values()) {
            if (site.getBeautyId() > 0) {
                count++;
            }
        }
        return count;
    }

    /**
     * 计算总产量
     * @param timeMillis
     * @return
     */
    private long calcAllSiteHarvest(long timeMillis) {
        long harvest = 0;
        for (UserColdRoomSite site : userColdRoomSiteMap.values()) {
            if (site.getBeautyId() == 0) {
                continue;
            }
            harvest += calcSiteHarvest(site, timeMillis);
        }
        return harvest;
    }


    /**
     * 计算产量
     * @param coldRoomSite
     * @param timeMillis
     * @return
     */
    private long calcSiteHarvest(UserColdRoomSite coldRoomSite, long timeMillis) {
        long harvest = 0;
        if (coldRoomSite.getBeautyId() == 0 || timeMillis < coldRoomSite.getLastRestoreTime()) {
            return harvest;
        }

        long lastZeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp(coldRoomSite.getLastRestoreTime());
        long add = ((timeMillis - lastZeroTime) / (60 * 60 * 1000 * 24)) * GameConfig.COLDROOM_DAY_HARVEST;
        if (add > 0) {
            harvest += add;
        }
        return harvest;
    }

    public UserColdRoomSite getUserColdRoomSite(int index) {
        return userColdRoomSiteMap.get(index);
    }
    public int getSiteNum() {
        return userColdRoomSiteMap.size();
    }

    /**
     * 同步冷宫信息
     */
    private void syncColdRoomSiteData(Map<Integer, UserColdRoomSite> siteMap) {
        List<UserColdRoomSite> siteList = new ArrayList<>();
        if (siteMap != null) {
            siteList.addAll(siteMap.values());
        }
        syncColdRoomSiteData(siteList);
    }

    /**
     * 同步冷宫信息
     */
    private void syncColdRoomSiteData(List<UserColdRoomSite> siteList) {
        if (siteList.size() == 0) {
            return;
        }
        player.sendPacket(Protocol.U_COLDROOM_SITE_SYNC, ColdRoomPb.parseColdRoomSiteListMsg(siteList));
    }

    public Map<Integer, UserColdRoomSite> getUserColdRoomSiteMap() {
        return userColdRoomSiteMap;
    }
}
